cmake_minimum_required(VERSION 3.1)
project(testif VERSION 2.6.5)

if (LLVM_VERSION_MAJOR LESS 10)
set(CMAKE_CXX_STANDARD 11)
elseif(LLVM_VERSION_MAJOR LESS 16)
set(CMAKE_CXX_STANDARD 14)
else()
set(CMAKE_CXX_STANDARD 17)

endif()

# add_compile_options(-g) "replaced with cmake -DCMAKE_BUILD_TYPE=Debug/Release"
if (NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Debug)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if (CMAKE_COMPILER_IS_GNUCXX)
  if(CYGWIN)
    set(CMAKE_CXX_FLAGS_DEBUG "-g -Og")
  elseif(MINGW)
    set(CMAKE_CXX_FLAGS_DEBUG "-g -O0  -Wa,-mbig-obj")
    set(CMAKE_CXX_FLAGS "-fuse-ld=lld")
    add_definitions(-DNDEBUG)
    if(WIN32)
      set(CMAKE_INSTALL_LIBDIR "lib")
    endif()
  endif()
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")

find_package(nlohmann_json QUIET)
if (NOT nlohmann_json_FOUND)
  find_path(JSON_INCLUDE_DIR nlohmann/json.hpp HINTS /usr/local/include)
  if(JSON_INCLUDE_DIR STREQUAL "JSON_INCLUDE_DIR-NOTFOUND")
    message(FATAL_ERROR "nlohmann json header file not found")
  endif()
endif()
include_directories(${JSON_INCLUDE_DIR})

# find_package(LLVM REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "Using ClangConfig.cmake in: ${CLANG_CMAKE_DIR}")
message(STATUS "Using LLVM libraries in: ${LLVM_LIBRARY_DIR}")

include_directories(${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_definitions(-DCLANG_RUNTIME_DIR="${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}")

# set(Boost_USE_MULTITHREADED ON)
# find_package(Boost REQUIRED COMPONENTS filesystem system)
include_directories(${BOOST_INCLUDEDIR})
find_package(Boost REQUIRED COMPONENTS filesystem system)

add_subdirectory("common")
add_subdirectory("incparser")

if (CMAKE_COMPILER_IS_GNUCXX AND MINGW)
    add_executable(testif main.cpp libtestud.cpp testud.cpp testif.cpp testhelper.cpp testvisitor.cpp libtestif.cpp ifparser.cpp dependency_graph.cpp ifpreprocessor.cpp)
else()
    add_library(libtestif libtestud.cpp testud.cpp testif.cpp testhelper.cpp testvisitor.cpp libtestif.cpp ifparser.cpp dependency_graph.cpp ifpreprocessor.cpp)
    SET_TARGET_PROPERTIES(libtestif PROPERTIES OUTPUT_NAME "testif")
    #SET_TARGET_PROPERTIES(libtestif PROPERTIES PUBLIC_HEADER fixed_address.h)
    add_executable(testif main.cpp)
    target_link_libraries(testif libtestif)
endif()


if (nlohmann_json_FOUND)
  target_link_libraries(testif nlohmann_json::nlohmann_json)
else()
  find_library(nlohmann_LIBRARY nlohmann HINTS /usr/local/lib)
  if (NOT nlohmann_LIBRARY STREQUAL "nlohmann_LIBRARY-NOTFOUND")
    target_link_libraries(testif ${nlohmann_LIBRARY})
  endif()
endif()

target_link_libraries(testif
  # Boost::filesystem
  # Boost::system
  ${Boost_LIBRARIES}

  rocket::incparser
  rocket::common
)

if (CLANG_LINK_CLANG_DYLIB)
target_link_libraries(testif
  clang-cpp
  clang
)
else()
target_link_libraries(testif
  clangTooling
  clangFrontendTool
  clangFrontend
  clangDriver
  clangSerialization
  clangCodeGen
  clangParse
  clangSema
  clangStaticAnalyzerFrontend
  clangStaticAnalyzerCheckers
  clangStaticAnalyzerCore
  clangAnalysis
  clangARCMigrate
  clangRewriteFrontend
  clangRewrite
  clangEdit
  clangASTMatchers
  clangAST
  clangLex
  clangBasic
)
endif()

if(LLVM_LINK_LLVM_DYLIB)
  message(STATUS "linking against dynamical libraries of LLVM")
  find_library(found_LLVM LLVM HINTS ${LLVM_LIBRARY_DIRS})
  if(found_LLVM)
    message(STATUS "linking against monolithic LLVM")
    target_link_libraries(testif LLVM)
  else()
    find_library(found_LLVM_V LLVM-${LLVM_VERSION_MAJOR} HINTS ${LLVM_LIBRARY_DIRS})
    if(found_LLVM_V)
      message(STATUS "linking against monolithic LLVM")
      target_link_libraries(testif LLVM-${LLVM_VERSION_MAJOR})
    else()
      set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support core irreader)
    endif()
  endif()
else()
  llvm_map_components_to_libnames(llvm_libs ${LLVM_TARGETS_TO_BUILD} support core irreader)
  target_link_libraries(testif ${llvm_libs})
endif()

configure_file(testifConfig.cmake.in testifConfig.cmake @ONLY)

# make install 安装目标：程序、库文件、头文件等
if (CMAKE_COMPILER_IS_GNUCXX AND MINGW)
    install(TARGETS testif
            RUNTIME DESTINATION bin
            ARCHIVE DESTINATION lib
            INCLUDES DESTINATION include
            )
else()
    install(TARGETS testif libtestif EXPORT testif
            RUNTIME DESTINATION bin
            ARCHIVE DESTINATION lib
            INCLUDES DESTINATION include
            )
    install(FILES libtestif.h
            DESTINATION include
            )
    install(FILES libtestud.h
            DESTINATION include
            )
    install(EXPORT testif NAMESPACE smartrocket DESTINATION lib/cmake)
    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/testifConfig.cmake" DESTINATION lib/cmake)
endif()

# cpack 命令制作安装包
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/ticpsh/smart-rocket/unit/core")
set(CPACK_PACKAGE_NAME "smartrocket-core-testif")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "SmartRocket Core test interface toolset")
set(CPACK_PACKAGE_VENDOR "TICPSH")
set(CPACK_RPM_PACKAGE_URL "https://www.ticpsh.com")
set(CPACK_PACKAGE_CONTACT "zhouzhenghui@ticpsh.com")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
set(CPACK_RPM_PACKAGE_DESCRIPTION "SmartRocket Core test interface generator for C/C++")
set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_CURRENT_LIST_DIR}/ChangeLog")
set(CPACK_RPM_PACKAGE_RELOCATABLE)

# Path to file containing pre (un)install script.
# set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE)
# set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE)

# Path to file containing pre (un)install script.
# set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE)
# set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE)

set(CPACK_GENERATOR "RPM")
include(CPack)
